#include <Arduino.h>
#include <Wire.h>
#include <DHT.h>
#include <BH1750.h>
#include "ai_farm_analyzer.h"

// 定义传感器引脚
#define DHTPIN 2
#define DHTTYPE DHT22
#define SOIL_MOISTURE_PIN A0
#define CO2_SENSOR_PIN A1

// 初始化传感器
DHT dht(DHTPIN, DHTTYPE);
BH1750 lightMeter;

// 传感器控制器类
class SensorController {
private:
  // 校准参数
  float tempOffset;        // 温度校准偏移量
  float humidityOffset;    // 湿度校准偏移量
  int soilMoistureDry;     // 干燥时的土壤湿度传感器值
  int soilMoistureWet;     // 湿润时的土壤湿度传感器值
  bool sensorsInitialized; // 传感器初始化状态
  
  // 过滤参数
  static const int FILTER_SIZE = 5;
  float tempReadings[FILTER_SIZE];
  float humidityReadings[FILTER_SIZE];
  float soilMoistureReadings[FILTER_SIZE];
  int filterIndex;
  
  // 内部方法
  float applyMedianFilter(float readings[], float newValue);
  int readCo2Sensor();
  float convertSoilSensorValueToPercentage(int sensorValue);

public:
  // 构造函数
  SensorController();
  
  // 初始化函数
  void init();
  
  // 读取所有传感器数据
  FarmEnvironmentData readAllSensors();
  
  // 单独读取各种传感器
  float readTemperature();
  float readHumidity();
  float readSoilMoisture();
  uint32_t readLightIntensity();
  uint16_t readCo2Level();
  
  // 校准方法
  void calibrateTemperature(float offset);
  void calibrateHumidity(float offset);
  void calibrateSoilMoisture(int dryValue, int wetValue);
  
  // 检查传感器状态
  bool isSensorHealthy();
};

// 构造函数
SensorController::SensorController() {
  tempOffset = 0.0f;
  humidityOffset = 0.0f;
  soilMoistureDry = 900; // 默认干燥值 (根据实际传感器调整)
  soilMoistureWet = 300; // 默认湿润值 (根据实际传感器调整)
  sensorsInitialized = false;
  filterIndex = 0;
  
  // 初始化过滤数组
  for (int i = 0; i < FILTER_SIZE; i++) {
    tempReadings[i] = 0.0f;
    humidityReadings[i] = 0.0f;
    soilMoistureReadings[i] = 0.0f;
  }
}

// 初始化函数
void SensorController::init() {
  // 初始化DHT传感器
  dht.begin();
  
  // 初始化光照传感器
  Wire.begin();
  lightMeter.begin();
  
  // 配置模拟输入引脚
  pinMode(SOIL_MOISTURE_PIN, INPUT);
  pinMode(CO2_SENSOR_PIN, INPUT);
  
  sensorsInitialized = true;
  
  // 预热传感器
  delay(2000);
  
  // 预填充过滤数组
  for (int i = 0; i < FILTER_SIZE; i++) {
    tempReadings[i] = readTemperature();
    humidityReadings[i] = readHumidity();
    soilMoistureReadings[i] = readSoilMoisture();
    delay(100);
  }
}

// 读取所有传感器数据
FarmEnvironmentData SensorController::readAllSensors() {
  FarmEnvironmentData data;
  
  if (!sensorsInitialized) {
    // 如果传感器未初始化，返回默认值
    data.temperature = 0.0f;
    data.humidity = 0.0f;
    data.soilMoisture = 0.0f;
    data.lightIntensity = 0;
    data.co2Level = 0;
    data.timestamp = 0;
    data.hourOfDay = 0;
    return data;
  }
  
  // 读取并应用过滤
  data.temperature = readTemperature();
  data.humidity = readHumidity();
  data.soilMoisture = readSoilMoisture();
  data.lightIntensity = readLightIntensity();
  data.co2Level = readCo2Level();
  
  return data;
}

// 读取温度
float SensorController::readTemperature() {
  if (!sensorsInitialized) return 0.0f;
  
  // 从DHT传感器读取温度
  float temperature = dht.readTemperature();
  
  // 检查读取是否成功
  if (isnan(temperature)) {
    Serial.println("DHT温度读取失败！");
    return 0.0f;
  }
  
  // 应用校准偏移量
  temperature += tempOffset;
  
  // 应用中值滤波
  temperature = applyMedianFilter(tempReadings, temperature);
  
  return temperature;
}

// 读取湿度
float SensorController::readHumidity() {
  if (!sensorsInitialized) return 0.0f;
  
  // 从DHT传感器读取湿度
  float humidity = dht.readHumidity();
  
  // 检查读取是否成功
  if (isnan(humidity)) {
    Serial.println("DHT湿度读取失败！");
    return 0.0f;
  }
  
  // 应用校准偏移量
  humidity += humidityOffset;
  
  // 确保湿度在合理范围内
  if (humidity < 0) humidity = 0;
  if (humidity > 100) humidity = 100;
  
  // 应用中值滤波
  humidity = applyMedianFilter(humidityReadings, humidity);
  
  return humidity;
}

// 读取土壤湿度
float SensorController::readSoilMoisture() {
  if (!sensorsInitialized) return 0.0f;
  
  // 读取土壤湿度传感器值
  int sensorValue = analogRead(SOIL_MOISTURE_PIN);
  
  // 转换为百分比
  float moisturePercentage = convertSoilSensorValueToPercentage(sensorValue);
  
  // 应用中值滤波
  moisturePercentage = applyMedianFilter(soilMoistureReadings, moisturePercentage);
  
  return moisturePercentage;
}

// 读取光照强度
uint32_t SensorController::readLightIntensity() {
  if (!sensorsInitialized) return 0;
  
  // 从BH1750传感器读取光照强度
  uint16_t lux = lightMeter.readLightLevel();
  
  // BH1750的最大读数约为65535 lux，这里转换为uint32_t
  return (uint32_t)lux;
}

// 读取CO2浓度
uint16_t SensorController::readCo2Level() {
  if (!sensorsInitialized) return 0;
  
  // 读取CO2传感器值 (简化版)
  // 在实际应用中，应根据具体的CO2传感器型号实现相应的读取逻辑
  int sensorValue = readCo2Sensor();
  
  // 这里使用简化的转换公式，实际应用中应根据传感器的校准曲线进行调整
  // 假设传感器值范围在0-1023之间，对应400-2000 ppm
  uint16_t co2ppm = 400 + (sensorValue * 1600 / 1023);
  
  return co2ppm;
}

// 校准温度
void SensorController::calibrateTemperature(float offset) {
  tempOffset = offset;
}

// 校准湿度
void SensorController::calibrateHumidity(float offset) {
  humidityOffset = offset;
}

// 校准土壤湿度
void SensorController::calibrateSoilMoisture(int dryValue, int wetValue) {
  soilMoistureDry = dryValue;
  soilMoistureWet = wetValue;
}

// 检查传感器状态
bool SensorController::isSensorHealthy() {
  if (!sensorsInitialized) return false;
  
  // 读取传感器数据，检查是否有合理值
  float temp = dht.readTemperature();
  float humid = dht.readHumidity();
  
  // 检查DHT传感器是否正常工作
  if (isnan(temp) || isnan(humid)) {
    return false;
  }
  
  // 检查光照传感器是否正常工作
  uint16_t lux = lightMeter.readLightLevel();
  if (lux == 0) {
    return false;
  }
  
  // 检查土壤湿度传感器是否正常工作
  int soilValue = analogRead(SOIL_MOISTURE_PIN);
  if (soilValue == 0 || soilValue == 1023) {
    return false;
  }
  
  return true;
}

// 应用中值滤波
float SensorController::applyMedianFilter(float readings[], float newValue) {
  // 添加新值到数组
  readings[filterIndex] = newValue;
  
  // 更新索引
  filterIndex = (filterIndex + 1) % FILTER_SIZE;
  
  // 创建临时数组进行排序
  float sortedValues[FILTER_SIZE];
  for (int i = 0; i < FILTER_SIZE; i++) {
    sortedValues[i] = readings[i];
  }
  
  // 简单冒泡排序
  for (int i = 0; i < FILTER_SIZE - 1; i++) {
    for (int j = 0; j < FILTER_SIZE - i - 1; j++) {
      if (sortedValues[j] > sortedValues[j + 1]) {
        // 交换值
        float temp = sortedValues[j];
        sortedValues[j] = sortedValues[j + 1];
        sortedValues[j + 1] = temp;
      }
    }
  }
  
  // 返回中值
  return sortedValues[FILTER_SIZE / 2];
}

// 读取CO2传感器值
int SensorController::readCo2Sensor() {
  // 简化的CO2传感器读取函数
  // 在实际应用中，应根据具体的CO2传感器型号实现相应的读取逻辑
  
  // 这里使用模拟输入作为示例
  int value = analogRead(CO2_SENSOR_PIN);
  
  // 为了演示目的，添加一些随机波动来模拟传感器读数
  int noise = random(-10, 10);
  value = constrain(value + noise, 0, 1023);
  
  return value;
}

// 将土壤传感器值转换为百分比
float SensorController::convertSoilSensorValueToPercentage(int sensorValue) {
  // 确保传感器值在合理范围内
  if (sensorValue <= soilMoistureWet) {
    return 100.0f; // 完全湿润
  } else if (sensorValue >= soilMoistureDry) {
    return 0.0f; // 完全干燥
  } else {
    // 线性映射到百分比
    return 100.0f - ((float)(sensorValue - soilMoistureWet) / 
                    (float)(soilMoistureDry - soilMoistureWet)) * 100.0f;
  }
}